package com.intellect.syncproject;


import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.DirectoryWalker;

public class SynchListREFilter extends DirectoryWalker {
	
	public List<String> fileExcluded = new ArrayList<String>();
	public List<String> dirExcluded = new ArrayList<String>();
	
	List<Pattern> dirExclusions = null;
	List<Pattern> fileExclusions = null;
	
	public SynchListREFilter() {
		
	}
	
	public SynchListREFilter(List<Pattern> dirExclusions, List<Pattern>fileExclusions) {
		this.dirExclusions = dirExclusions;
		this.fileExclusions = fileExclusions;
	}

	public void setDirExclusionRE(List<Pattern> dirExclusions) {
		this.dirExclusions = dirExclusions;
	}
	
	public void setFileExclusionsRE(List<Pattern> fileExclusions) {
		this.fileExclusions = fileExclusions;
	}
	
    public List<File> getList(File startDirectory) throws IOException {
      List<File> results = new ArrayList<File>();
      walk(startDirectory, results);
      return results;
    }
    
    @SuppressWarnings("unchecked")
	public List<File> getListSortedByCanonicalName(File startDirectory) throws IOException {
    	List<File> results = getList(startDirectory);
		Collections.sort(results, new Comparator() {

			@Override
			public int compare(Object arg0, Object arg1) {
				 try {
					return ((File)arg0).getCanonicalPath().compareTo(((File)arg1).getCanonicalPath());
				} catch (IOException e) {
					e.printStackTrace();
				}
				return 0;
			}
			
		});
		return results;
    }

    @SuppressWarnings("unchecked")
	protected boolean handleDirectory(File directory, int depth, Collection results) {
    	if( dirExclusions == null ) {
    		results.add(directory);
    		return true;
    	}
    	
    	String dirName = null;
		try {
			dirName = directory.getCanonicalPath();
		} catch (IOException e) {
			e.printStackTrace();
		}

		if( true ) {
			// Escape the path seperator...need this for window...what will happen on Unix????
	    	String[] dirParts = dirName.split("\\" + File.separator); 
	    	
	    	for( String subDir : dirParts ) {
	    		// If any of the RE in the exclusion list are enountered...reject the directory
	    		if( testRE(dirExclusions, subDir) ) {
	    			dirExcluded.add(dirName);
	    			return false;
	    		}
	    	}
		} else {
			if( testRE(dirExclusions, dirName) ) {
				dirExcluded.add(dirName);
				return false;
			} 
		}
    	// Save the directory...it's a good one!!
    	results.add(directory);
    	return true;
    }
    
    @SuppressWarnings("unchecked")
	protected void handleFile(File file, int depth, Collection results) {
    	if( fileExclusions == null ) {
    		results.add(file);
    		return;
    	}
    	
    	String fileName = null;
   		fileName = file.getName();
   		
   		if( testRE(fileExclusions, fileName) ) {
   			fileExcluded.add(fileName);
   		} else {
   			results.add(file);
   		}
    }

    public boolean testRE(List<Pattern> reList, String name) {
    	for( Pattern p : reList) {
    		Matcher match = p.matcher(name);
    		if( match.find() == true ) {
    			return true;
    		}
    	}
    	return false;
    }
}
